#ifndef CENGINE_H
#define CENGINE_H


#include "CMacros.h"



class CEngine : public CSingleTon<CEngine>
{
public:
	~CEngine();
	CEngine();
	
	static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);

	bool Setup(int Width,int Height,bool Windowed);
	bool SetupWindow();
	bool SetupFps();
	void BEGINRENDER(int Red,int Green,int Blue);
	void ENDRENDER();
	void ShowFPS();
	void RenderWired();
	void RenderSolid();
	void CleanUP();
	int  EnterLoop(bool SetupScene(),void RenderScene(),void CleanScene());

	void SetProjection(float Fov,float Near,float Far);
	void SetBasicCamera(D3DXVECTOR3 Eye,D3DXVECTOR3 Look,D3DXVECTOR3 Up);
	void SetTransform(D3DTRANSFORMSTATETYPE Type,D3DXMATRIX *Temp);
	void SetWorldTransform(D3DXMATRIX *Temp);
	void SetTranslation(D3DXMATRIX *Temp,float x,float y,float z);
	void LoadTexture(LPDIRECT3DTEXTURE9 *Texture,std::string filename);

	HWND              &GetHWND()  {return hWND;}
	LPDIRECT3DDEVICE9 &GetDevice(){return device;}

	int GetWindowWidth() {return m_Width;}
	int GetWindowHeight(){return m_Height;}
	
	int    GetRandom(int Min,int Max);
	int    ShowMouse(bool Visible);
	double ConvertToDegree(double Radian);
	double ConvertToRadian(double Degree);

	float GetDistance(D3DXVECTOR3 Player,D3DXVECTOR3 Object);
public:
	template <class X>
	void SafeRelease(X *&p)
	{
		if (p){
		p->Release();
		p = NULL;
		}
	}
	template <class X>
	void SafeDelete(X *&p)
	{
		if(p){
			delete p;
			p =NULL;
		}
	}
	template <class X>
	void SafeDeleteArray(X *&p)
	{
		if(p){
			delete[] p;
			p =NULL;
		}
	}
	template<typename T>
	std::string ToString(const T& obj) 
	{
		std::stringstream ss;
		ss << obj;
		return ss.str();
	}
private:

	HWND              hWND;
	HINSTANCE         hInstance;
	LPDIRECT3D9       direct3d;
	LPDIRECT3DDEVICE9 device;	

	int  m_Width;
	int  m_Height;
	bool m_Windowed;	

	LPD3DXFONT m_FpsFont;
};
#endif